#! /usr/bin/env python
# -*- coding: utf-8 -*-
###############################################################################
#       start-bundle.py
#       
#       Copyright © 2008, Florian Birée <florian@biree.name>
#       
#       This file is a part of Croquant
#       <http://code.google.com/p/croquant/>
#       
#       This program is free software: you can redistribute it and/or modify
#       it under the terms of the GNU General Public License as published by
#       the Free Software Foundation, either version 2 of the License, or
#       (at your option) any later version.
#       
#       This program is distributed in the hope that it will be useful,
#       but WITHOUT ANY WARRANTY; without even the implied warranty of
#       MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
#       GNU General Public License for more details.
#       
#       You should have received a copy of the GNU General Public License
#       along with this program.  If not, see <http://www.gnu.org/licenses/>.
#       
###############################################################################
"""This script starts a MoinMoin server and open this wiki in Crunchy"""

__author__ = "Florian Birée"
__version__ = "0.1.0"
__license__ = "GPL"
__copyright__ = "Copyright © 2008, Florian Birée"
__revision__ = "$Revision: $"
__date__ = "$Date: $"

import os
import sys
import subprocess

MOIN_PREFIX = "moin-"
MOIN_START = "wikiserver.py"
MOIN_URL = "http://127.0.0.1:8080/"
CRUNCHY_DIR = "crunchy"
CRUNCHY_START = "crunchy.py"

class Popen(subprocess.Popen):
    """Subclass of Popen to allow to terminate the process"""
    
    def terminate(self):
        """Terminate the process"""
        if self.poll() is not None:
            # Already close, don't take the risk to kill another process
            return
        if os.name == 'nt':
            # Windows stuff
            # From http://aspn.activestate.com/ASPN/Cookbook/Python/Recipe/347462
            import ctypes
            PROCESS_TERMINATE = 1
            handle = ctypes.windll.kernel32.OpenProcess(PROCESS_TERMINATE, False, self.pid)
            ctypes.windll.kernel32.TerminateProcess(handle, -1)
            ctypes.windll.kernel32.CloseHandle(handle)
        else:
            from signal import SIGTERM
            os.kill(self.pid, SIGTERM)

if __name__ == '__main__':
    bundle_path = os.path.realpath(os.path.dirname(sys.argv[0]))
    # Find the MoinMoin installation: a subdir wich name begin by MOIN_PREFIX
    # and followed the highter number
    subdirs = os.listdir(bundle_path)
    moin_dirs = [dir for dir in subdirs if dir.startswith(MOIN_PREFIX)]
    moin_dirs.sort()
    moin_path = os.path.join(bundle_path, moin_dirs[-1])
    
    # Start MoinMoin
    moin_process = Popen(
        "%(python)s %(moin_start)s" % {
            'python': sys.executable,
            'moin_start': os.path.join(moin_path, MOIN_START),
        },
        shell=True,
    )
    
    # Start Crunchy with the MoinMoin FrontPage
    crunchy_process = Popen(
        "%(python)s %(crunchy_start)s --url=%(moin_url)s" % {
            'python': sys.executable,
            'crunchy_start': os.path.join(bundle_path, CRUNCHY_DIR, CRUNCHY_START),
            'moin_url': MOIN_URL,
        },
        shell=True,
    )
    
    # Main loop
    try:
        crunchy_process.wait()
    except KeyboardInterrupt:
        print("Received Keyboard Interrupt, Quitting...")
    crunchy_process.terminate()
    moin_process.terminate()
